//
// Created by tcj on 2022/7/12.
//


#ifndef WEB_TEST_BUFFER_H
#define WEB_TEST_BUFFER_H


#include "vector"
#include "atomic"
#include "cstring"
#include "string"
#include "threadpool.h"
#include<unistd.h> //read() write()
#include<sys/uio.h> //readv() writev()

using namespace std;

namespace tcj{
    class Buffer{
    public:
        Buffer(int initBufferSize=1024);
        ~Buffer()=default;

        // 缓冲区可以读取的字节数
        ssize_t writeableBytes() const;
        // 缓冲区可以写入的字节数
        ssize_t readableBytes() const;
        // 缓冲区已经读取的字节数
        size_t readBytes() const;


//        readv和writev函数用于在一次函数调用中读、写多个非连续缓冲区。
//        有时也将这两个函数称为散布读（scatter read）和聚集写（gather write）
//        readv(fd,iov,iovcnt)
//        writev(fd,iov,iovcnt)
//        fd是要在其上进行读或是写的文件描述符；
//        iov是读或写所用的I/O向量；
//        iovcnt是要使用的向量元素个数。
        ssize_t ReadFd(int fd,int* Errno);
        ssize_t WriteFd(int fd,int* Errno);

        // 需要实现向buffer缓冲区中添加数据的方法
        void append(const char* str,size_t len);
        void append(const std::string& str);
        void append(const void* str,size_t len);
        void append(const Buffer& buffer);


        // 保证数据可以写入缓冲区
        void allocateSpace(size_t len);

        // 更新读，写位置
        void updateReadPtr(size_t len);
        void updateReadPtrUntilEnd(const char* end);
        void updateWritePtr(size_t len);
        void initPtr();

        // 以指针方式的取现在指针
        const char* curReadPtr() const;
        const char* curWritePtrconst() const;
        char* curWritePtr();

        // 将缓冲区的数据转化成字符串
        std::string AlltoStr();
    private:
        // 返回值向缓冲区初始位置的指针
        char *BeginPtr_();
        // 开始的指针
        const char* BeginPtr_() const;
        // 缓冲池扩容
        void ensureWriteable(size_t len);

        std::vector<char> buffer_;
        std::atomic<std::size_t> readPos_;
        std::atomic<std::size_t> writePos_;
    };
}



#endif //WEB_TEST_BUFFER_H
